home *** CD-ROM | disk | FTP | other *** search
/ Ultimedia 1 / Ultimedia 1.iso / tools / grafiktools / showpicasso / source / showpicassov1.05.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-08  |  21.7 KB  |  897 lines

  1. /*
  2. **
  3. **      Projekt         : ShowPicasso - IFF für PicassoII
  4. **      Version         : 1.05a
  5. **      File            : ShowPicasso
  6. **      Status          : Public Domain
  7. **
  8. **      Autor           : Michael Ranner
  9. **      Datum           :  7. November 1993
  10. **      Letzte Änderung :  9. Juli 1994
  11. **
  12. **      This programm will only run, if the monitor file supplied
  13. **      with your graphics card is installed and running.
  14. **
  15. **      Anmerkung       : Bei der Programmierung von V1.055 sind Bugs aufgedeckt
  16. **                        worden, die nun nachträglich gefixt wurden.
  17. **
  18. */
  19.  
  20. extern struct Library *SysBase;
  21. extern struct Library *DOSBase;
  22. struct Library   *VilIntuiBase;
  23. struct Library  *IntuitionBase;
  24. struct Library       *IconBase;
  25. struct Library  *WorkbenchBase;
  26. struct Library        *AslBase;
  27. struct Library        *GfxBase;
  28. struct Library   *IFFParseBase;
  29. struct Library     *LocaleBase;
  30.  
  31. #include "ShowPicasso.h"
  32.  
  33. struct Catalog *catalog = NULL;
  34.  
  35.  
  36. /* Versionsstring und Template */
  37.  
  38. static UBYTE version[] = "$VER: ShowPicasso 1.05a - © Michael Ranner (09.07.94)";
  39. static UBYTE templ[]   = "FILENAME/M,DD=DEFDIR/K,PAT/K,CB=CBUF/K/N,NC=NOCENTER/S,NS=NOAUTOSCROLL/S,"
  40.                          "BH=BEHIND/S,HI15/S,HI16/S,QU=QUIET/S,RHEIGHT/K/N,RWIDTH/K/N,RTOP/K/N,"
  41.                          "RLEFT/K/N,APPICON/S,INAME/K,ITOP/K/N,ILEFT/K/N,PUBSCREEN/K";
  42.  
  43. static struct {
  44.                UBYTE  **pics;
  45.                UBYTE   *ddir;
  46.                UBYTE   *pat;
  47.                LONG    *cbuf;
  48.                LONG   nocent;
  49.                LONG   noscrl;
  50.                LONG   behind;
  51.                LONG     hi15;
  52.                LONG     hi16;
  53.                LONG    quiet;
  54.                LONG *rheight;
  55.                LONG  *rwidth;
  56.                LONG    *rtop;
  57.                LONG   *rleft;
  58.                LONG  appicon;
  59.                UBYTE  *iname;
  60.                LONG    *itop;
  61.                LONG   *ileft;
  62.                UBYTE *pubscr;
  63.               } cliparams = { NULL,NULL,NULL,NULL,FALSE,FALSE,FALSE,FALSE,FALSE,
  64.                               FALSE,NULL,NULL,NULL,NULL,FALSE,NULL,NULL,NULL,NULL };
  65.  
  66.  
  67. /* Locale Strings */
  68.  
  69. STRPTR localstr[11];
  70.  
  71. /* Strukturen für den Picassoscreen */
  72.  
  73. struct TagItem screentags[] = { { TAVIS_SCREEN_WIDTH },
  74.                                 { TAVIS_SCREEN_HEIGHT },
  75.                             { TAVIS_SCREEN_DEPTH },
  76.                                 { TAVIS_OPEN_BEHIND, FALSE },
  77.                                 { TAVIS_BEST_MODEID, TRUE },
  78.                                 { TAVIS_ALLOW_FALLBACK },
  79.                                 { TAVIS_AUTOSCROLL, TRUE },
  80.                                 { TAG_DONE } };
  81.  
  82. struct TagItem modetags[] = { { TAVIS_SCREEN_WIDTH },
  83.                               { TAVIS_SCREEN_HEIGHT },
  84.                           { TAVIS_SCREEN_DEPTH },
  85.                               { TAG_DONE } };
  86.  
  87. struct NewWindow     nw;  
  88. struct Screen *s = NULL;
  89. struct Window *w = NULL;
  90.  
  91.  
  92. /* Globale Flags */
  93.  
  94. UWORD        IFFSTATE; /* Flags für IFF */
  95. UWORD USERFLGS = NULL; /* Programm Flags User/Privat */
  96.  
  97.  
  98. /* Strukturen für das AppIcon */
  99.  
  100. struct DiskObject *appdobj = NULL;
  101. struct MsgPort    *appport = NULL;
  102. struct AppIcon    *appicon = NULL;
  103. struct AppMessage  *appmsg = NULL;
  104.  
  105. static UBYTE diconname[] = "ShowPicasso"; /* Defaultname des AppIcon */
  106. STRPTR              iconname = diconname;
  107. ULONG          itop = NULL, ileft = NULL; /* Positionsvariable des AppIcon */
  108.  
  109.  
  110. /* Filenamenliste */
  111.  
  112. BPTR           *dirlock = NULL; /* Zeiger auf ein Array von Directory Locks bei WBStart */
  113. STRPTR        *filename = NULL; /* Zeiger auf ein Array von Filenamen */
  114. UBYTE             nfile = NULL; /* Anzahl der Files */
  115.  
  116.  
  117. /* Programmname und Name des PubScreen */
  118.  
  119. STRPTR     mynamebuffer = NULL; /* eigener Programmname */
  120. STRPTR       pubscrname = NULL; /* Zeiger auf Namen eines PubScreen */
  121.  
  122.  
  123. /* Strukturen für ASL File Requester */
  124.  
  125. static UBYTE nullstr[]  = "";   /* Nullstring für Filerequester */
  126. static UBYTE dpatstr[]  = "#?"; /* Defaultpatternstring für Filerequester */
  127.  
  128. STRPTR       dirname = nullstr; /* Zeiger auf Directory des Filerequester */
  129. STRPTR       pattern = dpatstr; /* Zeiger auf Pattern des Filerequester */
  130.  
  131. struct FileRequester *freq = NULL;
  132. struct RDArgs         *rda = NULL;
  133. struct DiskObject    *dobj = NULL;
  134.  
  135. ULONG       aslh,aslw,aslt,asll; /* Angaben des User für Größe und Position des Filerequester */
  136.  
  137. struct TagItem ASLFRtags[] = { { ASLFR_TitleText, (LONG)"ShowPicasso 1.05" },
  138.                                { ASL_FuncFlags, FILF_MULTISELECT|FILF_PATGAD },
  139.                                { ASL_Dir },
  140.                                { ASL_Pattern },
  141.                                { ASL_Height },
  142.                                { ASL_Width },
  143.                                { ASL_LeftEdge },
  144.                                { ASL_TopEdge },
  145.                                { ASLFR_Screen },
  146.                                { TAG_DONE } };
  147.  
  148.  
  149. /* IFF ILBM */
  150.  
  151. struct IFFHandle *picture = NULL;
  152. BitMapHeader        *bmhd = NULL;
  153. UBYTE              *color = NULL;
  154.  
  155.  
  156. /* Buffer für Entpackroutine */
  157.  
  158. ULONG          cbufsize = 0x4000;   /* Defaultgröße von cbuf für AllocVec() */
  159. UBYTE               *cbuf = NULL;   /* Zwischenspeicher für gecrunchte Daten */
  160.  
  161.  
  162. /* Unterroutinen */
  163.  
  164.  
  165. #include "sp_protos.h"
  166. #include "sp_catalog.c"
  167. #include "sp_tools.c"
  168. #include "sp_iff.c"
  169.  
  170.  
  171. /* Öffnen und Schließen der Bild Datei 
  172. **
  173. ** Gibt einen BYTE Wert zurück der das Dateiformat bestimmt.
  174. ** 0 Fehler
  175. ** 1 IFF-ILBM
  176. ** 2 IFF-RGBN
  177. ** 3 IFF-RGB8
  178. **
  179. */
  180.  
  181. BYTE OpenPic(UBYTE *picname)
  182. {
  183.  BPTR filehandle = NULL;
  184.  LONG error;
  185.  BYTE type;
  186.  
  187.  if( picture = AllocIFF() )
  188.  {
  189.  
  190.   if(filehandle = Open(picname,MODE_OLDFILE))
  191.   {
  192.    picture->iff_Stream = filehandle;
  193.    InitIFFasDOS(picture);
  194.  
  195.    if(!OpenIFF(picture, IFFF_READ))
  196.    {
  197.     if(type = IsIFF(picture)) return(type); 
  198.     else error = MSG_NOTKNOWN;
  199.     CloseIFF(picture);
  200.    }
  201.    else error = MSG_EOPENIFF;
  202.   }
  203.   else error = MSG_NOFILE;
  204.  }
  205.  else error = MSG_EALLOCMEM;
  206.  
  207.  if(filehandle)
  208.  { 
  209.   Close(filehandle);
  210.   picture->iff_Stream = NULL;
  211.  }
  212.  
  213.  if(error) OutText(localstr[error]);
  214.  
  215.  return(NULL);
  216. }
  217.  
  218. VOID ClosePic(BPTR filehandle)
  219. {
  220.  if(picture)
  221.  { 
  222.   CloseIFF(picture);
  223.   FreeIFF(picture);
  224.   Close(filehandle);
  225.  }
  226. }
  227.  
  228. /* Öffnen eines Picasso Screen */
  229.  
  230. BOOL OpenDisplay(BitMapHeader *bmap,ULONG mode)
  231. {
  232.  struct  DimensionInfo dimension;
  233.  DisplayInfoHandle        handle; 
  234.  
  235.  UBYTE        sd = bmap->nPlanes;
  236.  UWORD              sw = bmap->w;
  237.  UWORD              sh = bmap->h;
  238.  BOOL            TRYAGAIN = TRUE;
  239.  
  240.  if(USERFLGS & UFLG_BEHIND) screentags[3].ti_Data = TRUE; /* Screen Behind */
  241.  
  242.  if(sd == 12) sd = 15L;                 /* Screentiefe 15 Bit bei 12 Planes */
  243.  if(USERFLGS & PFLG_TRUECLR)
  244.  {
  245.   if(USERFLGS & PFLG_TC15BIT) sd = 15L; /* Screentiefe 15 Bit bei Hicolor */
  246.   if(USERFLGS & PFLG_TC16BIT) sd = 16L; /* Screentiefe 16 Bit bei Hicolor */
  247.  }
  248.  if(mode & HAM_KEY)
  249.  {
  250.   if(sd == 6) sd = 15L;                 /* Screentiefe 15 Bit bei HAM6 */
  251.   if(sd == 8) sd = 24L;                 /* Screentiefe 24 Bit bei HAM8 */
  252.  }
  253.  
  254. TryAgain:
  255.  
  256.  if(!(USERFLGS & UFLG_NOSCROLL))
  257.  {
  258.   modetags[0].ti_Data = sw;
  259.   modetags[1].ti_Data = sh;
  260.   modetags[2].ti_Data = sd;
  261.   screentags[4].ti_Tag = TAVIS_SCREEN_MODEID;
  262.   screentags[4].ti_Data = VillageBestModeID(modetags);
  263.  
  264.   if(handle = FindDisplayInfo(screentags[4].ti_Data))
  265.   {
  266.    if(GetDisplayInfoData(handle,(UBYTE *)&dimension,sizeof(dimension),DTAG_DIMS,TAG_DONE))
  267.    {
  268.     if(dimension.Nominal.MaxX+1 > sw) sw = dimension.Nominal.MaxX+1;
  269.     if(dimension.Nominal.MaxY+1 > sh) sh = dimension.Nominal.MaxY+1;
  270.    }
  271.   }
  272.  }
  273.  
  274.  screentags[0].ti_Data = sw; /* Screenweite */
  275.  screentags[1].ti_Data = sh; /* Screenhöhe  */
  276.  screentags[2].ti_Data = sd; /* Screentiefe */
  277.  
  278.  
  279.  if(s = OpenVillageScreenTagList(screentags))
  280.  {
  281.   nw.LeftEdge  = 0; 
  282.   nw.TopEdge   = 0;
  283.   nw.Width     = s->Width;
  284.   nw.Height    = s->Height;
  285.   nw.FirstGadget = NULL; 
  286.   nw.Title     = NULL;
  287.   nw.IDCMPFlags= IDCMP_VANILLAKEY | IDCMP_MOUSEBUTTONS;
  288.   nw.Flags     = WFLG_BACKDROP | WFLG_BORDERLESS | WFLG_RMBTRAP | WFLG_ACTIVATE;
  289.   nw.Type      = CUSTOMSCREEN;
  290.   nw.Screen    = s;
  291.  
  292.   if (w = OpenWindow(&nw)) return(TRUE);
  293.  }
  294.  else 
  295.  {
  296.   if(TRYAGAIN)
  297.   {
  298.    if((USERFLGS & PFLG_TRUECLR) && (USERFLGS & UFLG_AUTO16))
  299.    {
  300.     sd = 16;
  301.     USERFLGS |= PFLG_TC16BIT;
  302.     TRYAGAIN = FALSE;
  303.     goto TryAgain;
  304.    }
  305.   }
  306.  }
  307.  return(FALSE);
  308. }
  309.  
  310. VOID CloseDisplay(VOID)
  311. {
  312.  if(w) 
  313.  {
  314.   CloseWindow(w);
  315.   w = NULL;
  316.  }
  317.  if(s) 
  318.  {
  319.   CloseVillageScreen(s);
  320.   s = NULL;
  321.  }
  322. }
  323.  
  324.  
  325. /* Shell bzw. WB Argumente einlesen */
  326.  
  327.  
  328. VOID GetArgs(int arg,struct WBStartup *wbs)
  329. {
  330.  struct WBArg *wbarg;
  331.  
  332.  UBYTE   **toolarray;
  333.  STRPTR       string;
  334.  BPTR          olock;
  335.  BPTR          dlock;
  336.  register     LONG i;
  337.  
  338.  
  339.  if(arg) /* Start von Shell */
  340.  {
  341.  
  342.   if(rda = ReadArgs(templ,(LONG *)&cliparams,NULL))
  343.   {
  344.    if(cliparams.ddir) dirname = cliparams.ddir;
  345.    if(cliparams.pat) pattern = cliparams.pat;
  346.    if(cliparams.pubscr) pubscrname = cliparams.pubscr;
  347.    if(cliparams.cbuf) cbufsize = *(cliparams.cbuf) * 1024L;
  348.    if(cliparams.nocent) USERFLGS |= UFLG_NOCENTER;
  349.    if(cliparams.noscrl) USERFLGS |= UFLG_NOSCROLL;
  350.    if(cliparams.behind) USERFLGS |= UFLG_BEHIND;
  351.    if(cliparams.hi15) USERFLGS |= PFLG_TC15BIT;
  352.    if(cliparams.hi16) USERFLGS |= PFLG_TC16BIT;
  353.    if(cliparams.quiet) USERFLGS |= UFLG_QUIET;
  354.    if(cliparams.rheight) aslh = *(cliparams.rheight);
  355.    if(cliparams.rwidth) aslw = *(cliparams.rwidth);
  356.    if(cliparams.rtop) aslt = *(cliparams.rtop);
  357.    if(cliparams.rleft) asll = *(cliparams.rleft);
  358.    if(cliparams.appicon) USERFLGS |= UFLG_APPICON;
  359.    if(cliparams.iname) iconname = cliparams.iname;
  360.    if(cliparams.itop)  itop = *(cliparams.itop);
  361.    if(cliparams.ileft) ileft = *(cliparams.ileft);
  362.    if(cliparams.pics && !(USERFLGS & UFLG_APPICON)) /* Bei APPICON wird die Angabe von Files ignoriert */
  363.    {
  364.     USERFLGS |= PFLG_CLIARGS;
  365.  
  366.     FOREVER
  367.     {
  368.      if(!(cliparams.pics[nfile])) break;
  369.      nfile++;
  370.     }
  371.  
  372.     if(filename = AllocVec(4 * nfile,MEMF_PUBLIC|MEMF_CLEAR))
  373.     {
  374.      for(i=0; i < nfile; i++) filename[i] = cliparams.pics[i];
  375.     }
  376.    }
  377.   }
  378.  
  379.  }
  380.  else     /* Start von Workbench */
  381.  {
  382.   wbarg = wbs->sm_ArgList;
  383.   dlock = wbarg->wa_Lock;
  384.   olock = CurrentDir(dlock);
  385.   
  386.   if((wbarg->wa_Name) && (dobj=GetDiskObject(wbarg->wa_Name)))
  387.   {
  388.    toolarray = (UBYTE **)dobj->do_ToolTypes;
  389.    if(string = FindToolType(toolarray,"DEFDIR")) dirname = string;
  390.    if(string = FindToolType(toolarray,"PATTERN")) pattern = string;
  391.    if(string = FindToolType(toolarray,"CBUF"))
  392.    {
  393.     if(!(cbufsize = 1024L * stol(string))) cbufsize = 0x4000;
  394.    }
  395.    if(string = FindToolType(toolarray,"RHEIGHT")) aslh = stol(string);
  396.    if(string = FindToolType(toolarray,"RWIDTH")) aslw = stol(string);
  397.    if(string = FindToolType(toolarray,"RTOP")) aslt = stol(string);
  398.    if(string = FindToolType(toolarray,"RLEFT")) asll = stol(string);
  399.    if(MatchToolValue(FindToolType(toolarray,"CENTER"),"NO")) USERFLGS |= UFLG_NOCENTER;
  400.    if(MatchToolValue(FindToolType(toolarray,"AUTOSCROLL"),"NO")) USERFLGS |= UFLG_NOSCROLL;
  401.    if(MatchToolValue(FindToolType(toolarray,"BEHIND"),"YES")) USERFLGS |= UFLG_BEHIND;
  402.    if(MatchToolValue(FindToolType(toolarray,"APPICON"),"YES")) USERFLGS |= UFLG_APPICON;
  403.    if(string = FindToolType(toolarray,"INAME")) iconname = string;
  404.    if(string = FindToolType(toolarray,"ITOP")) itop = stol(string);
  405.    if(string = FindToolType(toolarray,"ILEFT")) ileft = stol(string);
  406.    if(string = FindToolType(toolarray,"HICOLOR"))
  407.    {
  408.     if(MatchToolValue(string,"15")) USERFLGS |= PFLG_TC15BIT;
  409.     if(MatchToolValue(string,"16")) USERFLGS |= PFLG_TC16BIT;
  410.     if(MatchToolValue(string,"AUTO")) USERFLGS |= UFLG_AUTO16;
  411.    }
  412.    if(string = FindToolType(toolarray,"PUBSCREEN")) pubscrname = string;
  413.   }
  414.  
  415.   CurrentDir(olock);
  416.  
  417.   if((wbs->sm_NumArgs) > 1 && !(USERFLGS & UFLG_APPICON)) /* Bei APPICON werden Files als Argumente ignoriert */
  418.   {
  419.    USERFLGS |= PFLG_WBARGS;
  420.  
  421.    nfile = (wbs->sm_NumArgs) - 1;
  422.  
  423.    if((dirlock = AllocVec(nfile * 4,MEMF_PUBLIC|MEMF_CLEAR)) &&
  424.       (filename = AllocVec(nfile * 4,MEMF_PUBLIC|MEMF_CLEAR)))
  425.    {
  426.     for(i=0; i < nfile; i++)
  427.     {
  428.      wbarg++;
  429.      if(wbarg->wa_Lock) { dirlock[i] = wbarg->wa_Lock; }
  430.      else { dirlock[i] = dlock; }
  431.      filename[i] = wbarg->wa_Name;
  432.     }
  433.    }
  434.  
  435.   }
  436.  }  
  437. }
  438.  
  439.  
  440. /* Installation des AppIcons auf der WB */
  441.  
  442.  
  443. BOOL InstallAppIcon(struct WBStartup *wbs)
  444. {
  445.  STRPTR        myname;
  446.  
  447.  if(USERFLGS & PFLG_WBSTART)
  448.  {
  449.   myname = ((struct WBArg *)(wbs->sm_ArgList))->wa_Name; /* Programname aus Struktur */
  450.  }
  451.  else
  452.  {
  453.   myname = mynamebuffer;
  454.   GetProgramName(myname,64L); /* Programname durch Funktion */
  455.  }
  456.  
  457.  if(appdobj = GetDiskObject(myname))
  458.  {
  459.   appdobj->do_Type = WBAPPICON;
  460.   appdobj->do_CurrentX = ileft;
  461.   appdobj->do_CurrentY = itop;
  462.  
  463.   if(appport = CreateMsgPort())
  464.   {
  465.    if(appicon = AddAppIconA(0L,0L,iconname,appport,NULL,appdobj,NULL))
  466.    {
  467.     return(TRUE);
  468.    }
  469.   }
  470.  }
  471.  return(FALSE);
  472. }
  473.  
  474.  
  475. /* Entfernen des AppIcon von der WB */
  476.  
  477.  
  478. VOID DeleteAppIcon(VOID)
  479. {
  480.  if(appicon) RemoveAppIcon(appicon);
  481.  if(appport)
  482.  {
  483.   while(appmsg = (struct AppMessage *)GetMsg(appport)) ReplyMsg((struct Message *)appmsg);
  484.   DeleteMsgPort(appport); /* Mögliche Messages auslesen, MsgPort entfernen */
  485.  }
  486.  if(appdobj) FreeDiskObject(appdobj);
  487. }
  488.  
  489.  
  490. /* ASL Filerequester */
  491.  
  492.  
  493. BOOL FileRequest(void)
  494. {
  495.  struct Screen *pubscr;
  496.  struct WBArg  *frargs;
  497.  
  498.  ULONG  rheight = 400L;
  499.  ULONG   rwidth = 318L;
  500.  ULONG      rleft,rtop;
  501.  BOOL    error = FALSE;
  502.  register       LONG i;
  503.  
  504.  if(pubscr = LockPubScreen(pubscrname))
  505.  {
  506.  
  507.   if(!freq)
  508.   {
  509.  
  510.    if(aslh)
  511.    {
  512.     rheight = aslh; /* Benutzerwert für Requesterhöhe übernehmen */
  513.     if(rheight < 155) rheight = 155L;
  514.    }
  515.    else
  516.    {
  517.     if(pubscr->Height <= 400) rheight = 200L; /* Defaultwerte */
  518.    }
  519.  
  520.    if(aslw)
  521.    {
  522.     rwidth = aslw; /* Benutzerwert übernehmen; Default Requesterweite ist 318 */
  523.     if(rwidth < 262) rwidth = 262L;
  524.    }
  525.  
  526.    if(asll) rleft = asll;  /* Benutzerwert für Left Position übernehmen */
  527.    else rleft = (pubscr->Width -  rwidth) / 2;  /* Default: Requester in der Mitte zentriert. */
  528.  
  529.    if(aslt) rtop = aslt; /* Benutzerwert für Top Position übernehmen */
  530.    else rtop  = (pubscr->Height - rheight) / 2; /* -''- */
  531.  
  532.    ASLFRtags[2].ti_Data = (LONG)dirname; /* Parameter in die Tags schreiben */
  533.    ASLFRtags[3].ti_Data = (LONG)pattern;
  534.    ASLFRtags[4].ti_Data = rheight;
  535.    ASLFRtags[5].ti_Data = rwidth;
  536.    ASLFRtags[6].ti_Data = rleft;
  537.    ASLFRtags[7].ti_Data = rtop;
  538.    ASLFRtags[8].ti_Data = (LONG)pubscr;
  539.  
  540.    /* Abfrage auf Workbench 2.1, wenn ja, kann Requester auf jedem Pubscreen öffnen */
  541.  
  542.    if((AslBase->lib_Version) < 38L) ASLFRtags[8].ti_Tag = TAG_DONE; 
  543.  
  544.    freq = (struct FileRequester *)AllocAslRequest(ASL_FileRequest,ASLFRtags);
  545.  
  546.   }
  547.  
  548.   if(freq)
  549.   {
  550.  
  551.    if(AslRequest(freq,NULL))
  552.    {
  553.  
  554.     if(nfile = freq->rf_NumArgs)
  555.     {
  556.      frargs = freq->rf_ArgList;
  557.      dirname = freq->rf_Dir;
  558.  
  559.      if(filename = AllocVec(4 * nfile,MEMF_PUBLIC|MEMF_CLEAR))
  560.      {
  561.       for(i = 0; i < freq->rf_NumArgs; i++) filename[i] = frargs[i].wa_Name;
  562.      } 
  563.     } 
  564.    }
  565.    else error = TRUE;
  566.  
  567.   }
  568.   else error = TRUE;
  569.  
  570.   UnlockPubScreen(NULL,pubscr);
  571.  }
  572.  else
  573.  {
  574.   OutText(localstr[MSG_NOPUBSCR]);
  575.   error = TRUE;
  576.  }
  577.  
  578.  return(error);
  579. }
  580.  
  581.  
  582. /* Anzeigen des Bildes bzw. der Bilder */
  583.  
  584.  
  585. VOID ViewPicture(STRPTR *picfilename, STRPTR picdirname, BPTR *picdirlock)
  586. {
  587.  struct      Message *msg=NULL;
  588.  struct  ContextNode *top=NULL;
  589.  
  590.  BPTR              dlock,olock; /* Lock des aktuellen, bzw. alten Verzeichnisses */
  591.  BYTE                 datatype; /* Art des IFF Files */
  592.  ULONG                  modeid;
  593.  ULONG                  ncolor; /* Anzahl der Farben */
  594.  
  595.  LONG               error=NULL;
  596.  LONG          filecnt,size[4];
  597.  /* ULONG         secs,mics,secs1; */
  598.  register LONG             i,j;
  599.  
  600.  if(filename)
  601.  {
  602.  
  603.   if(dirname) dlock = Lock(dirname,ACCESS_READ); 
  604.  
  605.   for(filecnt=0; filecnt < nfile; filecnt++)
  606.   {
  607.    IFFSTATE = NULL;
  608.    USERFLGS &= 0xfeff;
  609.  
  610.    if(USERFLGS & UFLG_AUTO16) USERFLGS &= 0xf0ff; /* Falls "HICOLOR=AUTO" Hicolor Bits  wieder löschen */
  611.  
  612.    if(USERFLGS & PFLG_WBARGS) { olock = CurrentDir(dirlock[filecnt]); }
  613.    else { if(dirname) olock = CurrentDir(dlock); }
  614.  
  615.    if(datatype = OpenPic(filename[filecnt]))
  616.    {
  617.  
  618.     switch(datatype)
  619.     {
  620.      case 1:
  621.  
  622.      IFFSTATE |= ILBMFLG;
  623.      break;
  624.  
  625.      case 2:
  626.  
  627.      IFFSTATE |= RGBNFLG;
  628.      break;
  629.  
  630.      case 3:
  631.  
  632.      IFFSTATE |= RGB8FLG;
  633.      break;
  634.     }
  635.  
  636.     FOREVER
  637.     {
  638.      error=ParseIFF(picture,IFFPARSE_RAWSTEP);
  639.  
  640.      if(error == IFFERR_EOC) continue;
  641.      else if(error) error = MSG_MIFFILBM;
  642.  
  643.      if(top=CurrentChunk(picture))
  644.      {
  645.  
  646.       if((top->cn_ID) == ID_BMHD)
  647.       {
  648.        if(IFFSTATE & BMHDFLG) error = MSG_CHKEXIST2;
  649.        else
  650.        {
  651.         if(GetBMHD(picture,bmhd))
  652.         {
  653.          if(bmhd->nPlanes == 13)                 /* Pseudo 13 für RGBN */
  654.          {
  655.           bmhd->nPlanes = 12;
  656.          }
  657.          if(bmhd->nPlanes == 24) USERFLGS |= PFLG_TRUECLR;
  658.          if(bmhd->nPlanes == 25)                 /* Pseudo 25 für RGB8 */
  659.          {
  660.           USERFLGS |= PFLG_TRUECLR;
  661.           bmhd->nPlanes = 24;
  662.          }
  663.         }
  664.         else error = MSG_MIFFILBM;
  665.         IFFSTATE |= BMHDFLG;
  666.        }
  667.        ncolor = 1L<<bmhd->nPlanes;
  668.       }
  669.  
  670.       if((top->cn_ID) == ID_CAMG) 
  671.       {
  672.        if(IFFSTATE & CAMGFLG) error = MSG_CHKEXIST2;
  673.        else
  674.        {
  675.         if(GetCAMG(picture,&modeid))
  676.         {
  677.          if(modeid & EXTRAHALFBRITE_KEY)
  678.          {
  679.           ncolor = 32;
  680.          }
  681.          if(modeid & HAM_KEY)
  682.          {
  683.           if(bmhd->nPlanes == 6) ncolor = 16;
  684.           if(bmhd->nPlanes == 8) ncolor = 64;
  685.          }
  686.         }
  687.         else error = MSG_MIFFILBM;
  688.         IFFSTATE |= CAMGFLG;
  689.        }
  690.       }
  691.  
  692.       if((top->cn_ID) == ID_CMAP)
  693.       {
  694.        if(IFFSTATE & CMAPFLG) error = MSG_CHKEXIST2;
  695.        else
  696.        {
  697.         if(!((USERFLGS & PFLG_TRUECLR) || (IFFSTATE & RGBNFLG)))
  698.         {
  699.          if(!GetCMAP(picture,color,ncolor)) error = MSG_MIFFILBM;
  700.         }
  701.         IFFSTATE |= CMAPFLG;
  702.        }
  703.       }
  704.  
  705.       if((top->cn_ID) == ID_BODY)
  706.       {
  707.        if((IFFSTATE & BMHDFLG) && ((USERFLGS & PFLG_TRUECLR) || (IFFSTATE & CMAPFLG) || (IFFSTATE & RGBNFLG))) break;
  708.        else error = MSG_MIFFILBM;
  709.       }
  710.      }
  711.      if(error) break;
  712.     }
  713.  
  714.     /* CurrentTime(&secs,&mics); */
  715.  
  716.     if((!error) && OpenDisplay(bmhd,modeid))
  717.     {
  718.  
  719.      /* Kein Error nur möglich wenn BODY Chunk gefunden 
  720.         Auslesen der Chunk Daten, konvertieren und in   
  721.         die Bitmap schreiben. Farbregister setzen */
  722.  
  723.      if((IFFSTATE & CMAPFLG) && !(USERFLGS & PFLG_TRUECLR))
  724.      {
  725.       j=0;         
  726.  
  727.       Delay(2L);
  728.  
  729.       /* Without the Delay() function the color registers will not be correctly set.
  730.          This seems to be a bug in the firmware */
  731.          
  732.  
  733.       /* Das seltsame j<<(8-bmhd->nPlanes) kommt durch die seltsame
  734.          Planar => Chunky Konvertierung zustande (Assembler). */
  735.  
  736.       for(i=0; i <= (3*ncolor-3); i += 3)
  737.       {
  738.        SETRGB(s,j<<(8-bmhd->nPlanes),color[i],color[i+1],color[i+2]);
  739.        j++;
  740.       }
  741.  
  742.       if(modeid & EXTRAHALFBRITE_KEY)
  743.       {
  744.        for(i=0; i <= (3*ncolor-3); i += 3)
  745.        {
  746.         SETRGB(s,j<<(8-bmhd->nPlanes),color[i]>>1L,color[i+1]>>1L,color[i+2]>>1L);
  747.         j++;
  748.        }
  749.       }
  750.      }
  751.  
  752.      if(IFFSTATE & ILBMFLG)
  753.      {
  754.       if(!GetBODY_ILBM(picture,bmhd,modeid,s)) error = MSG_MIFFILBM;
  755.      }
  756.      else
  757.      {
  758.       if(!GetBODY_RGBx(picture,bmhd,s)) error = MSG_MIFFILBM;
  759.      }
  760.  
  761.      if(USERFLGS & UFLG_BEHIND) ScreenToFront(s);
  762.  
  763.      /* CurrentTime(&secs1,&mics); */
  764.  
  765.      if(!error)
  766.      {
  767.       Wait(WSig);
  768.       while(msg = GetMsg(w->UserPort)) ReplyMsg(msg);
  769.      }
  770.     }
  771.     else if(!error) error = MSG_NOSCR;
  772.     CloseDisplay();
  773.  
  774.     if(error) OutText(localstr[error]); /* Ausgabe der Fehlermeldung */
  775.  
  776.     if(!error && !(USERFLGS & (UFLG_QUIET | PFLG_WBSTART))) 
  777.     {
  778.      size[0] = bmhd->w;
  779.      size[1] = bmhd->h;
  780.      size[2] = bmhd->nPlanes;
  781.      size[3] = (LONG)filename[filecnt];
  782.      VPrintf("%ldx%ldx%ld : %s\n",size);
  783.    
  784.      /* error = secs1 - secs;
  785.         VPrintf(" - Zeit: %ld s\n",&error); */
  786.         
  787.     }
  788.  
  789.     ClosePic(picture->iff_Stream);
  790.    }
  791.  
  792.    if(USERFLGS & PFLG_WBARGS) { CurrentDir(olock); }
  793.    else { if(dirname) CurrentDir(olock); }
  794.   }
  795.  
  796.   if(dirname) UnLock(dlock);
  797.   if(dirlock) FreeVec(dirlock);
  798.    
  799.   FreeVec(filename);
  800.   dirlock = NULL;
  801.   filename = NULL;
  802.  }
  803. }
  804.  
  805.  
  806. /* Hauptprogramm */
  807.  
  808.  
  809. VOID main(int argc,struct WBStartup *wbs)
  810. {
  811.  BOOL    done = FALSE;
  812.  BOOL APPICON = FALSE;
  813.  register LONG      i;
  814.  
  815.  if(OpenLibs())
  816.  {
  817.  
  818.   if(LocaleBase)
  819.   {
  820.    catalog = OpenCatalogA(NULL,"showpicasso.catalog",NULL);
  821.    for(i = 0; i < 10L; i++) localstr[i+1] = GetString(i);
  822.   }
  823.  
  824.   if(!argc) USERFLGS |= PFLG_WBSTART;
  825.   GetArgs(argc,wbs);
  826.  
  827.   if(GetWorkSpace())
  828.   {
  829.  
  830.    if(USERFLGS & UFLG_APPICON) APPICON = InstallAppIcon(wbs);
  831.  
  832.    do
  833.    {
  834.  
  835.     if(APPICON)
  836.     {
  837.  
  838.      WaitPort(appport);
  839.      while(appmsg = (struct AppMessage *)GetMsg(appport))
  840.      {
  841.       if(appmsg->am_NumArgs == NULL)
  842.       {
  843.        done = FileRequest();
  844.        ViewPicture(filename, dirname, dirlock);
  845.       }
  846.       else if(appmsg->am_NumArgs > NULL)
  847.       {
  848.        nfile = appmsg->am_NumArgs;
  849.        if((dirlock = AllocVec(nfile * 4,MEMF_PUBLIC|MEMF_CLEAR)) &&
  850.           (filename = AllocVec(nfile * 4,MEMF_PUBLIC|MEMF_CLEAR)))
  851.        {
  852.         for(i=0; i < nfile; i++)
  853.         {
  854.          dirlock[i] = appmsg->am_ArgList[i].wa_Lock;
  855.          filename[i] = appmsg->am_ArgList[i].wa_Name;
  856.         }
  857.        }
  858.        done = FALSE;
  859.        USERFLGS |= PFLG_WBARGS;
  860.        ViewPicture(filename, dirname, dirlock);
  861.       }
  862.       ReplyMsg((struct Message *)appmsg);
  863.      }
  864.      USERFLGS &= 0x1fff;
  865.  
  866.     }
  867.     else
  868.     {
  869.  
  870.      if(USERFLGS & (PFLG_CLIARGS | PFLG_WBARGS))
  871.      {
  872.       done = TRUE;
  873.       ViewPicture(filename, dirname, dirlock);
  874.      }
  875.      else
  876.      {
  877.       done = FileRequest();
  878.       ViewPicture(filename, dirname, dirlock);
  879.      }
  880.  
  881.     }
  882.  
  883.    } while(!done);
  884.  
  885.    if(USERFLGS & UFLG_APPICON) DeleteAppIcon(); /* AppIcon entfernen */
  886.    if(dobj) FreeDiskObject(dobj);
  887.    if(freq) FreeAslRequest(freq);
  888.    if(rda) FreeArgs(rda);
  889.  
  890.    FreeWorkSpace();
  891.   }
  892.   else OutText(localstr[MSG_EALLOCMEM]);
  893.  }
  894.  else OutText(localstr[MSG_EOPENLIBS]);
  895.  CloseLibs();
  896. }
  897.